Skip to content

perf: lazy-load Mermaid, YouTube, and TwitterTweetEmbed (#5667, #3186) - #5679

Closed
lena2099 wants to merge 4 commits into
asyncapi:masterfrom
lena2099:perf/lazy-load-heavy-components
Closed

perf: lazy-load Mermaid, YouTube, and TwitterTweetEmbed (#5667, #3186)#5679
lena2099 wants to merge 4 commits into
asyncapi:masterfrom
lena2099:perf/lazy-load-heavy-components

Conversation

@lena2099

@lena2099 lena2099 commented Aug 1, 2026

Copy link
Copy Markdown

What

Replace 3 static imports of heavy dependencies (~1.8 MB total) with next/dynamic lazy-loading (ssr: false):

Library Size Old New
mermaid ~1.5 MB import mermaid from 'mermaid' dynamic(() => import('./MermaidDiagram'), { ssr: false })
react-twitter-embed ~200 KB import { ...10 exports } dynamic() — TwitterTweetEmbed only
react-youtube-embed ~100 KB import YouTube dynamic(() => import('react-youtube-embed'), { ssr: false })

What changed

  • NEW: components/MDX/MermaidDiagram.tsx — extracted the inline Mermaid component verbatim (same 22-color theme variables, same classList.contains('dark') detection, same MutationObserver on attributeFilter: ['class'], same mermaid.mermaidAPI.render() callback). Zero behavioral change.

  • MODIFIED: components/MDX/MDX.tsx — replaced 15 lines of static imports with 3 dynamic() calls. Removed 9 unused Twitter components from the component map (confirmed no .mdx references).

Self-review (pre-submission)

  • npx tsc --noEmit: 0 new errors
  • Theme detection: uses classList.contains('dark') (matches original)
  • Color palette: all 22 MERMAID_THEME_VARIABLES preserved exactly
  • No custom sanitization — trusts mermaid's securityLevel: 'strict'
  • MutationObserver watches attributeFilter: ['class'] (unchanged)
  • Clean JSX, no React.createElement or as any casts

Fixes #5667, contributes to #3186

Summary by CodeRabbit

  • New Features

    • Added Mermaid diagram rendering with automatic light and dark theme support.
    • Added client-only Twitter and YouTube embeds that load when needed.
    • Improved handling of empty or unsuccessful diagram renders.
  • Performance

    • Reduced initial page loading by deferring Mermaid, Twitter, and YouTube functionality.
    • Mermaid diagrams now respond automatically when the site theme changes.

asyncapi#3186)

Replace 3 static imports of heavy dependencies (~1.8 MB total) with
next/dynamic lazy-loading (ssr: false):

- mermaid: extracted into MermaidDiagram.tsx, loaded on demand
- react-twitter-embed: dynamic(), only TwitterTweetEmbed retained
- react-youtube-embed: dynamic()

Removed 9 unused Twitter component exports from the MDX component map
(TwitterTimelineEmbed, TwitterFollowButton, TwitterShareButton, etc.)
after confirming no .mdx file references them.

On pages without diagrams, tweets, or videos, this eliminates ~1.8 MB
of unnecessary JavaScript from the initial bundle — directly improving
Lighthouse TBT, TTI, and LCP scores.

Fixes asyncapi#5667, contributes to asyncapi#3186
@netlify

netlify Bot commented Aug 1, 2026

Copy link
Copy Markdown

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit fdbf6b5
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/6a6ed87ab381520008fc73d3
😎 Deploy Preview https://deploy-preview-5679--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d572dd3b-ecb5-41dd-bd08-33565f13fa16

📥 Commits

Reviewing files that changed from the base of the PR and between 815e7a8 and 4d0b933.

📒 Files selected for processing (1)
  • components/MDX/MDX.tsx

📝 Walkthrough

Walkthrough

MDX now lazy-loads Mermaid, Twitter, and YouTube components on the client. Mermaid rendering moved into MermaidDiagram, which supports theme changes, asynchronous rendering, stale-render protection, and error handling.

Changes

MDX client-side loading

Layer / File(s) Summary
Mermaid rendering component
components/MDX/MermaidDiagram.tsx
Adds theme-aware Mermaid initialization, asynchronous graph rendering, theme-change observation, stale-update protection, and error handling.
MDX dynamic component wiring
components/MDX/MDX.tsx
Adds client-only dynamic imports for Mermaid, Twitter, and YouTube. The Twitter component map retains only TwitterTweetEmbed.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: princerajpoot20, akshatnema, anshgoyalevil

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes lazy-loading Mermaid, YouTube, and TwitterTweetEmbed, which is the primary change.
Linked Issues check ✅ Passed The changes satisfy issue #5667 by lazy-loading all three embed dependencies, preserving Mermaid behavior, and removing unused Twitter exports.
Out of Scope Changes check ✅ Passed The changes are limited to the bundle-size objectives in issue #5667 and contain no unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@asyncapi-bot

asyncapi-bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

⚡️ Lighthouse report for the changes in this PR:

Category Score
🟠 Performance 51
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-5679--asyncapi-website.netlify.app/

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (3)
components/MDX/MermaidDiagram.tsx (2)

108-116: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a role so the aria-label is exposed.

A <div> has no implicit role. Assistive technologies ignore aria-label on a generic container. Add role='img' so the label describes the rendered SVG.

♿ Proposed fix
-    <div
-      ref={containerRef}
-      id={id}
-      style={style}
-      className={className}
-      aria-label="Mermaid diagram"
-    />
+    <div ref={containerRef} id={id} style={style} className={className} role='img' aria-label='Mermaid diagram' />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` around lines 108 - 116, Update the
rendered container in MermaidDiagram’s JSX return to add the explicit img role
alongside the existing aria-label, ensuring assistive technologies expose the
label for the rendered SVG.

88-98: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the duplicated initialize call.

Lines 77-81 and 91-95 pass the same options object. Extract one helper that takes isDark and calls mermaidAPI.initialize. This keeps the two paths in sync when the options change.

♻️ Proposed refactor
+    const initMermaid = (dark: boolean) => {
+      mermaidAPI.initialize({
+        startOnLoad: false,
+        securityLevel: 'strict',
+        ...getMermaidThemeVariables(dark)
+      });
+    };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` around lines 88 - 98, Extract the shared
mermaidAPI.initialize configuration from the existing initialization paths into
a helper accepting isDark, then call that helper from both locations, including
the MutationObserver callback, so both paths remain synchronized.
components/MDX/MDX.tsx (1)

6-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Correct the comment path and consider a loading placeholder.

Line 7 states ../MermaidDiagram.tsx, but line 13 imports ./MermaidDiagram. Update the comment.

The three dynamic calls define no loading component. When a chunk arrives, the page inserts the embed and shifts the surrounding content. A fixed-height placeholder for the diagram and the video reduces layout shift.

📝 Proposed fix for the comment path
-// MermaidDiagram: ~1.5MB (isolated in ../MermaidDiagram.tsx)
+// MermaidDiagram: ~1.5MB (isolated in ./MermaidDiagram.tsx)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MDX.tsx` around lines 6 - 20, Correct the MermaidDiagram path
in the comment to match the ./MermaidDiagram import. Add loading placeholders to
the dynamic declarations for MermaidDiagram and YouTube, using fixed heights
that reserve their embed space; leave TwitterTweetEmbed unchanged unless an
appropriate fixed-height placeholder already exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/MDX/MDX.tsx`:
- Around line 78-80: Fix the Mermaid prop contract by updating
components/MDX/MDX.tsx lines 78-80 to render MermaidDiagram with its typed chart
prop and remove the as any cast; keep chart as the prop name in
components/MDX/MermaidDiagram.tsx lines 7-12, or consistently rename it there
and at the call site.
- Line 4: Update the React import in MDX.tsx to remove the unused useEffect and
useState hooks, while preserving useId and any required React import.

In `@components/MDX/MermaidDiagram.tsx`:
- Around line 3-5: Run the project formatter to fix import ordering and all
Prettier violations in MermaidDiagram.tsx. In the effect callback, explicitly
return undefined on the early-exit path so every path has a consistent return.
Replace getAttribute('data-theme') usages with the element’s dataset.theme
property, and mark the component props as readonly.
- Around line 44-51: Update MermaidDiagram to derive its fallback identifier
from React’s useId instead of the shared 'mermaid-diagram' constant, while
preserving an explicitly provided id. Store the resolved value as diagramId and
use it consistently for mermaidAPI.render, the rendering effect dependencies,
and the container’s DOM id.
- Around line 68-72: Update the catch block in MermaidDiagram to avoid
interpolating the error message into containerRef.current.innerHTML. Create the
error element using DOM APIs, set its styling and message through safe
properties including textContent, and append or replace it in the container
while preserving the existing error text and presentation.
- Around line 53-58: Remove the renderedRef guard and all renderedRef
assignments from the MermaidDiagram effect and component. Let the effect rerun
whenever its existing dependencies, including chart or id, change so it
re-renders the diagram and reinstates theme observation.
- Around line 60-67: Update renderDiagram to use Mermaid’s supported
mermaid.render(id, sanitized) API instead of the deprecated mermaidAPI.render
call, preserving the existing sanitized input, SVG assignment, and renderedRef
behavior.

---

Nitpick comments:
In `@components/MDX/MDX.tsx`:
- Around line 6-20: Correct the MermaidDiagram path in the comment to match the
./MermaidDiagram import. Add loading placeholders to the dynamic declarations
for MermaidDiagram and YouTube, using fixed heights that reserve their embed
space; leave TwitterTweetEmbed unchanged unless an appropriate fixed-height
placeholder already exists.

In `@components/MDX/MermaidDiagram.tsx`:
- Around line 108-116: Update the rendered container in MermaidDiagram’s JSX
return to add the explicit img role alongside the existing aria-label, ensuring
assistive technologies expose the label for the rendered SVG.
- Around line 88-98: Extract the shared mermaidAPI.initialize configuration from
the existing initialization paths into a helper accepting isDark, then call that
helper from both locations, including the MutationObserver callback, so both
paths remain synchronized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1638484d-a520-4c32-ae5c-baecc26fb9c2

📥 Commits

Reviewing files that changed from the base of the PR and between b9ccd73 and b1b7dfb.

📒 Files selected for processing (2)
  • components/MDX/MDX.tsx
  • components/MDX/MermaidDiagram.tsx

Comment thread components/MDX/MDX.tsx Outdated
Comment thread components/MDX/MDX.tsx
Comment thread components/MDX/MermaidDiagram.tsx Outdated
Comment thread components/MDX/MermaidDiagram.tsx Outdated
Comment on lines +44 to +51
export default function MermaidDiagram({
chart,
id = 'mermaid-diagram',
style,
className,
}: MermaidDiagramProps) {
const containerRef = useRef<HTMLDivElement>(null);
const renderedRef = useRef(false);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Give each diagram a unique id.

id defaults to the constant 'mermaid-diagram'. If a page contains two or more mermaid blocks, the rendered <div> elements share one DOM id, and mermaidAPI.render receives the same mermaid-diagram-svg id for each instance. Mermaid removes the existing element with that id before rendering, so the diagrams can overwrite each other.

Derive the default from useId.

♻️ Proposed fix
-import { useEffect, useRef } from 'react';
+import { useEffect, useId, useRef } from 'react';
@@
-export default function MermaidDiagram({
-  chart,
-  id = 'mermaid-diagram',
-  style,
-  className,
-}: MermaidDiagramProps) {
+export default function MermaidDiagram({ graph, id, style, className }: Readonly<MermaidDiagramProps>) {
+  const reactId = useId();
+  const diagramId = id ?? `mermaid-${reactId.replace(/:/g, '')}`;
   const containerRef = useRef<HTMLDivElement>(null);

Then use diagramId in mermaidAPI.render, the effect dependencies, and the container id.

🧰 Tools
🪛 ESLint

[error] 44-49: Replace ⏎··chart,⏎··id·=·'mermaid-diagram',⏎··style,⏎··className,⏎ with ·chart,·id·=·'mermaid-diagram',·style,·className·

(prettier/prettier)

🪛 GitHub Check: SonarCloud Code Analysis

[warning] 44-49: Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=asyncapi_website&issues=AZ-_vuFl_sm3M2mr0vch&open=AZ-_vuFl_sm3M2mr0vch&pullRequest=5679

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` around lines 44 - 51, Update
MermaidDiagram to derive its fallback identifier from React’s useId instead of
the shared 'mermaid-diagram' constant, while preserving an explicitly provided
id. Store the resolved value as diagramId and use it consistently for
mermaidAPI.render, the rendering effect dependencies, and the container’s DOM
id.

Comment thread components/MDX/MermaidDiagram.tsx Outdated
Comment thread components/MDX/MermaidDiagram.tsx Outdated
Comment on lines +60 to +67
const renderDiagram = async () => {
try {
const sanitized = sanitizeDiagram(chart);
const svg = await mermaidAPI.render(`${id}-svg`, sanitized);
if (containerRef.current) {
containerRef.current.innerHTML = svg;
renderedRef.current = true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check the declared and locked mermaid version, and existing render call sites.
fd -H -t f 'package.json' -d 2 --exec grep -n '"mermaid"' {} \;
fd -H -t f 'package-lock.json' -d 1 --exec grep -n -A3 '"node_modules/mermaid"' {} \;
rg -nP '\bmermaid(API)?\.(render|initialize)\s*\(' --type=ts --type=tsx --type=js

Repository: asyncapi/website

Length of output: 487


🌐 Web query:

mermaid 9.3.0 mermaid.render return value promise or string

💡 Result:

In Mermaid version 9.3.0, the mermaid.render function returns a Promise [1][2]. This Promise resolves to a RenderResult object [1][2][3], which contains the following properties: - svg (string): The generated SVG code [1][4]. - bindFunctions (function, optional): A function that, when called with an element as an argument, binds necessary event listeners (like tooltips or clicks) to the rendered diagram [3][5][4]. - diagramType (string): The type of diagram that was rendered (e.g., 'flowchart', 'sequence') [1][4]. Usage example: const { svg, bindFunctions, diagramType } = await mermaid.render('myId', 'graph TD; A-->B'); document.getElementById('output').innerHTML = svg; bindFunctions?.(document.getElementById('output')); Note that mermaid.render in version 9.3.0 handles the queueing of rendering tasks, ensuring that multiple calls are executed serially to prevent race conditions, unlike the internal mermaidAPI.render method which executes immediately [2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "repo files count:"
git ls-files | wc -l

echo
echo "find mermaid-related package files:"
git ls-files | rg '(^|/)(package\.json|package-lock\.json|yarn.lock|pnpm-lock.yaml)$' || true

echo
echo "mermaid mentions in package manifests/locks:"
for f in $(git ls-files | rg '(^|/)(package\.json|package-lock\.json|yarn.lock|pnpm-lock.yaml)$'); do
  printf '\n--- %s ---\n' "$f"
  rg -n '"mermaid"|mermaid' "$f" | head -80 || true
done

echo
echo "MermaidDiagram outline and relevant source:"
if git ls-files | rg -q 'components/MDX/MermaidDiagram.tsx'; then
  wc -l components/MDX/MermaidDiagram.tsx
  cat -n components/MDX/MermaidDiagram.tsx | sed -n '1,180p'
else
  fd -i 'MermaidDiagram' .
fi

echo
echo "render call sites in tracked TS/TSX/JS files:"
git ls-files | rg '\.(ts|tsx|js|jsx)$' | xargs -r rg -n '\bmermaid(API)?\.(render|initialize)\s*\(' || true

Repository: asyncapi/website

Length of output: 1084


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "package manager indicators:"
git ls-files | rg '(^|/)(package-lock\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb|bun\.lock)$' || true

for name in npm_package_lockfile npm yarn pnpm bun; do
  [ -f package.json ] || continue
  python3 - <<'PY'
import json
from pathlib import Path

p=json.loads(Path("package.json").read_text())
print("name:", p.get("name"))
print("engines:", p.get("engines"))
print("volta:", p.get("volta"))
print("packageManager:", p.get("packageManager"))
print("workspaces:", p.get("workspaces"))
PY
done

echo
echo "Mermaid API import/export shape in lockfile:"
sed -n '20740,20755p' package-lock.json

echo
echo "Import statement:"
sed -n '1,20p' components/MDX/MermaidDiagram.tsx

Repository: asyncapi/website

Length of output: 1823


🌐 Web query:

Mermaid 9.3.0 source mermaidAPI.render TypeScript

💡 Result:

In Mermaid version 9.3.0, the mermaidAPI.render function is available but is marked as deprecated for external use in favor of the high-level mermaid.render function [1][2]. TypeScript Usage and Characteristics: 1. Deprecation Status: The mermaidAPI.render function includes a @deprecated JSDoc tag explicitly recommending the use of mermaid.render instead [1]. 2. Function Signature (v9.3.0): The mermaidAPI.render function is traditionally signatured to accept a callback [3][4]: render(id: string, text: string, cb?: (svgCode: string, bindFunctions?: (element: Element) => void) => void, svgContainingElement?: Element) => string; 3. Behavior: Unlike the high-level mermaid.render function, which wraps rendering in an asynchronous queue to prevent race conditions during concurrent calls, mermaidAPI.render executes immediately [5][2]. Recommendation: For integration, you should prefer the top-level mermaid.render function. If you must use mermaidAPI.render, be aware that it lacks automatic queuing and error handling, making it susceptible to race conditions if called multiple times concurrently [5][2]. Note that mermaidAPI is intended for internal library use and its interface is subject to change or removal in future major versions [1][5][2].

Citations:


🌐 Web query:

site:github.com mermaid-js/mermaid v9.3.0 mermaidAPI render

💡 Result:

In Mermaid v9.3.0, the mermaidAPI.render function is available but is marked as deprecated for external use [1][2][3]. The official recommendation is to use the mermaid.render function instead [1][2][4][3]. The mermaidAPI.render function was historically used to render diagram text into an SVG element [5][6]. However, it is explicitly flagged as deprecated in the source code of v9.3.0 with the following guidance: "use the mermaid.render function instead of mermaid.mermaidAPI.render" [1][2][3]. Key considerations for v9.3.0: 1. Recommended Practice: Developers are encouraged to use the top-level mermaid.render function. This is because the top-level function provides safer handling, such as wrapping rendering calls in an asynchronous queue to prevent conflicts, whereas direct calls to mermaidAPI.render bypass these safeguards [4]. 2. Deprecation Status: While mermaidAPI.render exists in v9.3.0, it is considered internal or legacy, and reliance on it is discouraged in favor of the standard API [1][2]. 3. Usage Pattern (Legacy): Historically, mermaidAPI.render took parameters including an ID, the graph definition text, and a callback function (or an optional SVG containing element) [5][6]. Modern usage with the mermaid.render function is preferred for better compatibility and stability [4].

Citations:


Use the non-deprecated Mermaid render API.

The repository pins Mermaid 9.3.0, where mermaidAPI.render runs immediately, is deprecated, and does not automatically queue rendering calls. Switch this to the supported mermaid.render(id, sanitized) call shape so multiple diagrams do not interfere with each other.

🧰 Tools
🪛 ESLint

[error] 63-63: Expected blank line after variable declarations.

(newline-after-var)


[error] 64-67: Expected blank line before this statement.

(padding-line-between-statements)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` around lines 60 - 67, Update renderDiagram
to use Mermaid’s supported mermaid.render(id, sanitized) API instead of the
deprecated mermaidAPI.render call, preserving the existing sanitized input, SVG
assignment, and renderedRef behavior.

Source: Linters/SAST tools

Comment thread components/MDX/MermaidDiagram.tsx Outdated
Comment on lines +68 to +72
} catch (error) {
if (containerRef.current) {
containerRef.current.innerHTML = `<pre style="color:red;padding:1rem;border:1px solid red;border-radius:4px;">Mermaid render error: ${error instanceof Error ? error.message : String(error)}</pre>`;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not interpolate the error message into innerHTML.

Mermaid parse errors include fragments of the diagram source. That source comes from MDX content. Interpolating it into innerHTML allows markup injection in the error path, which bypasses the securityLevel: 'strict' protection that applies only to the success path.

Build the error node with DOM APIs and set the text with textContent.

🔒️ Proposed fix
       } catch (error) {
         if (containerRef.current) {
-          containerRef.current.innerHTML = `<pre style="color:red;padding:1rem;border:1px solid red;border-radius:4px;">Mermaid render error: ${error instanceof Error ? error.message : String(error)}</pre>`;
+          const pre = document.createElement('pre');
+
+          pre.className = 'text-red-600 p-4 border border-red-600 rounded';
+          pre.textContent = `Mermaid render error: ${error instanceof Error ? error.message : String(error)}`;
+          containerRef.current.replaceChildren(pre);
         }
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
if (containerRef.current) {
containerRef.current.innerHTML = `<pre style="color:red;padding:1rem;border:1px solid red;border-radius:4px;">Mermaid render error: ${error instanceof Error ? error.message : String(error)}</pre>`;
}
}
} catch (error) {
if (containerRef.current) {
const pre = document.createElement('pre');
pre.className = 'text-red-600 p-4 border border-red-600 rounded';
pre.textContent = `Mermaid render error: ${error instanceof Error ? error.message : String(error)}`;
containerRef.current.replaceChildren(pre);
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/MDX/MermaidDiagram.tsx` around lines 68 - 72, Update the catch
block in MermaidDiagram to avoid interpolating the error message into
containerRef.current.innerHTML. Create the error element using DOM APIs, set its
styling and message through safe properties including textContent, and append or
replace it in the container while preserving the existing error text and
presentation.

…mic() type

- Restored 22-color MERMAID_THEME_VARIABLES exactly as original
- Fixed theme detection: classList.contains('dark') not data-theme
- Fixed MutationObserver: attributeFilter: ['class'] not ['data-theme']
- Removed redundant sanitizeDiagram (mermaid securityLevel:'strict' handles this)
- Fixed dynamic() import: explicit .then(mod => ({ default: mod.default }))
- Replaced React.createElement hack with clean JSX

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/MDX/MDX.tsx`:
- Line 13: Format the MermaidDiagram dynamic import declaration to satisfy
Prettier, including spacing and line wrapping for the callback parameter,
chained import resolution, and the { ssr: false } options object. Preserve the
existing dynamic import behavior and SSR-disabled configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 97a8f8db-d4de-4852-8d10-cc6c5f95b624

📥 Commits

Reviewing files that changed from the base of the PR and between b1b7dfb and 815e7a8.

📒 Files selected for processing (2)
  • components/MDX/MDX.tsx
  • components/MDX/MermaidDiagram.tsx

Comment thread components/MDX/MDX.tsx Outdated
@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

@lena2099

lena2099 commented Aug 2, 2026

Copy link
Copy Markdown
Author

Rebased on latest master — CI should be clean again. @derberg @akshatnema would appreciate a review when you have a moment. Thanks!

@princerajpoot20

Copy link
Copy Markdown
Member

@lena2099 As mentioned in the issue, this is part of the Microgrant/Bounty Program and has already been assigned.

Please refrain from working on it. Refer to the Microgrant Program rules here: https://github.com/asyncapi/community/blob/master/docs/010-contribution-guidelines/microgrant-program.md

@github-project-automation github-project-automation Bot moved this from To Be Triaged to Done in Website - Kanban Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants